package org.eiahe.hr.salary.controller;

import lombok.RequiredArgsConstructor;
import org.ehe.common.core.BaseController;
import org.ehe.common.core.domain.R;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.common.satoken.utils.LoginHelper;
import org.ehe.system.domain.HrEmployee;
import org.ehe.system.service.IHrEmployeeService;
import org.eiahe.hr.salary.domain.vo.EmployeeSalaryVo;
import org.eiahe.hr.salary.service.ISalaryStructureService;
import org.eiahe.hr.salary.service.IEmployeePhoneAssociationService;
import org.eiahe.hr.salary.mapper.SalaryStructureMapper;
import org.ehe.common.excel.utils.ExcelUtil;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletResponse;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.eiahe.hr.salary.domain.SalaryStructure;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.system.domain.vo.SysDeptVo;
import org.ehe.system.service.ISysDeptService;

/**
 * 员工薪资查询Controller
 *
 * @author zhangnn
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/salary/employee")
public class EmployeeSalaryController extends BaseController {

    private final ISalaryStructureService iSalaryStructureService;
    private final IHrEmployeeService employeeService;
    private final IEmployeePhoneAssociationService iPhoneAssociationService;
    private final SalaryStructureMapper baseMapper;
    private final ISysDeptService deptService;

    /**
     * 员工查询自己的薪资列表（根据手机号验证状态决定显示脱敏还是完整数据）
     *
     * @param yearMonth 年月(yyyyMM格式)
     * @param showFull  是否显示完整数据（需要手机号验证通过）
     */
    @GetMapping("/list")
    public TableDataInfo<EmployeeSalaryVo> list(@RequestParam(required = false) String yearMonth,
            @RequestParam(defaultValue = "false") boolean showFull) {
        // 获取当前登录员工的工号
        String employeeNo = getLoginEmployeeNo();

        // 检查是否需要显示完整数据且手机号已验证
        boolean displayFullData = showFull && iPhoneAssociationService.isPhoneNumberVerified(employeeNo);

        // 使用默认分页参数（查询全部数据）
        PageQuery pageQuery = new PageQuery(Integer.MAX_VALUE, 1);

        // 根据是否显示完整数据调用不同的服务方法
        if (displayFullData) {
            // 显示完整数据
            LambdaQueryWrapper<SalaryStructure> lqw = Wrappers.lambdaQuery();
            lqw.eq(SalaryStructure::getEmployeeNo, employeeNo);
            if (StringUtils.isNotBlank(yearMonth)) {
                lqw.eq(SalaryStructure::getYearMonth, yearMonth);
            }
            lqw.eq(SalaryStructure::getStatus, "0"); // 只查询正常状态的数据
            lqw.orderByDesc(SalaryStructure::getYearMonth);

            Page<SalaryStructure> page = baseMapper.selectPage(pageQuery.build(), lqw);
            List<EmployeeSalaryVo> employeeSalaryVos = page.getRecords().stream()
                    .map(this::convertToEmployeeSalaryVoWithFullData)
                    .collect(Collectors.toList());
            employeeSalaryVos.forEach(e -> {
                String department = e.getDepartment();
                if (StringUtils.isNotBlank(department)) {
                    try {
                        SysDeptVo sysDeptVo = deptService.selectDeptById(Long.valueOf(department));
                        if (Objects.nonNull(sysDeptVo)) {
                            e.setDepartment(sysDeptVo.getDeptName());
                        }
                    } catch (NumberFormatException ex) {
                        // 如果部门ID不是数字，保持原值
                    }
                }
            });

            Page<EmployeeSalaryVo> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
            resultPage.setRecords(employeeSalaryVos);
            return TableDataInfo.build(resultPage);
        } else {
            // 显示脱敏数据
            return iSalaryStructureService.queryEmployeeSalaryPageList(employeeNo, yearMonth, pageQuery);
        }
    }

    /**
     * 员工查询自己的薪资详情（敏感信息默认已模糊处理）
     *
     * @param structureId 薪资构成ID
     */
    @GetMapping("/{structureId}")
    public R<EmployeeSalaryVo> getInfo(@PathVariable Long structureId) {
        // 默认返回脱敏数据
        EmployeeSalaryVo salaryVo = iSalaryStructureService.getEmployeeSalaryDetail(structureId, true);
        if (salaryVo == null) {
            return R.fail("未找到对应的薪资信息");
        }
        // 这里应该添加权限校验，确保员工只能查询自己的薪资信息
        HrEmployee hrEmployee = employeeService.queryByUserId(LoginHelper.getUserId());
        if (Objects.nonNull(hrEmployee)) {
            if (!salaryVo.getEmployeeNo().equals(hrEmployee.getEmployeeNo())) {
                return R.fail("无权限查看！");
            }
        }
        return R.ok(salaryVo);
    }

    /**
     * 员工查询自己的完整薪资详情（需要特殊权限或验证）
     *
     * @param structureId 薪资构成ID
     * @param showFull    是否显示完整数据
     * @param phoneLast6  手机号后六位（用于验证身份）
     */
    @GetMapping("/{structureId}/detail")
    public R<EmployeeSalaryVo> getFullInfo(@PathVariable Long structureId,
            @RequestParam(defaultValue = "false") boolean showFull,
            @RequestParam(required = false) String phoneLast6) {
        // 获取当前登录员工的信息
        HrEmployee hrEmployee = employeeService.queryByUserId(15L);
        if (hrEmployee == null) {
            return R.fail("未找到员工信息");
        }

        // 查询薪资详情
        SalaryStructure salaryStructure = baseMapper.selectById(structureId);
        if (salaryStructure == null) {
            return R.fail("未找到对应的薪资信息");
        }

        // 验证是否为本人的薪资信息
        if (LoginHelper.getUserId() != 1L && !salaryStructure.getEmployeeNo().equals(hrEmployee.getEmployeeNo())) {
            return R.fail("无权限查看！");
        }

        // 如果请求显示完整数据，则需要验证手机号后六位
        if (showFull) {
            // 验证手机号后六位
            if(LoginHelper.getUserId() != 1L ){
                if (StringUtils.isBlank(phoneLast6) || phoneLast6.length() != 6 ||
                    !hrEmployee.getMobile().endsWith(phoneLast6)) {
                    return R.fail("手机号后六位验证失败");
                }
            }
            // 验证通过，返回完整数据
            EmployeeSalaryVo salaryVo = convertToEmployeeSalaryVoWithFullData(salaryStructure);
            salaryVo.setIsMasked(false);
            return R.ok(salaryVo);
        } else {
            // 即使showFull为false，如果提供了手机号后六位且验证通过，也返回完整数据
            if (StringUtils.isNotBlank(phoneLast6) && phoneLast6.length() == 6 &&
                    hrEmployee.getMobile().endsWith(phoneLast6)) {
                // 手机号验证通过，返回完整数据
                EmployeeSalaryVo salaryVo = convertToEmployeeSalaryVoWithFullData(salaryStructure);
                salaryVo.setIsMasked(false);
                return R.ok(salaryVo);
            } else {
                // 返回脱敏数据
                EmployeeSalaryVo salaryVo = convertToEmployeeSalaryVo(salaryStructure);
                salaryVo.setIsMasked(true);
                return R.ok(salaryVo);
            }
        }
    }

    /**
     * 导出员工薪资列表（根据手机号验证状态决定导出脱敏还是完整数据）
     *
     * @param yearMonth 年月(yyyyMM格式)
     * @param showFull  是否显示完整数据（需要手机号验证通过）
     */
    @PostMapping("/export")
    public void export(@RequestParam(required = false) String yearMonth,
            @RequestParam(defaultValue = "false") boolean showFull, HttpServletResponse response) {
        // 获取当前登录员工的工号
        String employeeNo = getLoginEmployeeNo();

        // 检查是否需要显示完整数据且手机号已验证
        boolean displayFullData = showFull && iPhoneAssociationService.isPhoneNumberVerified(employeeNo);

        List<EmployeeSalaryVo> list;
        if (displayFullData) {
            // 导出完整数据
            LambdaQueryWrapper<SalaryStructure> lqw = Wrappers.lambdaQuery();
            lqw.eq(SalaryStructure::getEmployeeNo, employeeNo);
            if (StringUtils.isNotBlank(yearMonth)) {
                lqw.eq(SalaryStructure::getYearMonth, yearMonth);
            }
            lqw.eq(SalaryStructure::getStatus, "0"); // 只查询正常状态的数据
            lqw.orderByDesc(SalaryStructure::getYearMonth);

            List<SalaryStructure> salaryList = baseMapper.selectList(lqw);
            list = salaryList.stream()
                    .map(this::convertToEmployeeSalaryVoWithFullData)
                    .collect(Collectors.toList());
        } else {
            // 导出脱敏数据
            list = iSalaryStructureService.queryEmployeeSalaryList(employeeNo, yearMonth);
        }
        ExcelUtil.exportExcel(list, "薪资条数据", EmployeeSalaryVo.class, response);
    }

    /**
     * 获取当前登录员工的工号
     *
     * @return 工号
     */
    private String getLoginEmployeeNo() {
        String empNo = null;
        HrEmployee hrEmployee = employeeService.queryByUserId(LoginHelper.getUserId());
        //HrEmployee hrEmployee = employeeService.queryByUserId(15L);
        if (Objects.nonNull(hrEmployee)) {
            empNo = hrEmployee.getEmployeeNo();
        }
        return empNo;
    }

    /**
     * 将SalaryStructure转换为EmployeeSalaryVo（完整数据，不脱敏）
     *
     * @param salaryStructure 薪资结构实体
     * @return 员工薪资VO
     */
    private EmployeeSalaryVo convertToEmployeeSalaryVoWithFullData(SalaryStructure salaryStructure) {
        EmployeeSalaryVo vo = new EmployeeSalaryVo();
        vo.setStructureId(salaryStructure.getStructureId());
        vo.setEmployeeNo(salaryStructure.getEmployeeNo());
        vo.setEmployeeName(salaryStructure.getEmployeeName());
        vo.setDepartment(salaryStructure.getDepartment());
        vo.setYearMonth(salaryStructure.getYearMonth());
        vo.setShouldAttendanceDays(salaryStructure.getShouldAttendanceDays());
        vo.setAbsenceDays(salaryStructure.getAbsenceDays());
        vo.setPaidAttendanceDays(salaryStructure.getPaidAttendanceDays());

        // 时间类型转换
        vo.setCreateTime(salaryStructure.getCreateTime());
        vo.setUpdateTime(salaryStructure.getUpdateTime());

        // 不进行模糊处理，直接显示完整数据
        vo.setJobLevelSalary(salaryStructure.getJobLevelSalary());
        vo.setBaseSalary(formatAmount(salaryStructure.getBaseSalary()));
        vo.setPositionSalary(formatAmount(salaryStructure.getPositionSalary()));
        vo.setPerformanceSalary(formatAmount(salaryStructure.getPerformanceSalary()));
        vo.setDutyAllowance(formatAmount(salaryStructure.getDutyAllowance()));
        vo.setAbsenceDeduction(formatAmount(salaryStructure.getAbsenceDeduction()));
        vo.setMealAllowance(formatAmount(salaryStructure.getMealAllowance()));
        vo.setOtherAdjustment(formatAmount(salaryStructure.getOtherAdjustment()));
        vo.setMealDeduction(formatAmount(salaryStructure.getMealDeduction()));
        vo.setGrossSalary(formatAmount(salaryStructure.getGrossSalary()));
        vo.setPensionDeduction(formatAmount(salaryStructure.getPensionDeduction()));
        vo.setUnemploymentDeduction(formatAmount(salaryStructure.getUnemploymentDeduction()));
        vo.setMedicalDeduction(formatAmount(salaryStructure.getMedicalDeduction()));
        vo.setMajorMedicalDeduction(formatAmount(salaryStructure.getMajorMedicalDeduction()));
        vo.setSocialInsurancePersonal(formatAmount(salaryStructure.getSocialInsurancePersonal()));
        vo.setHousingFundPersonal(formatAmount(salaryStructure.getHousingFundPersonal()));
        vo.setSocialHousingTotal(formatAmount(salaryStructure.getSocialHousingTotal()));
        vo.setTaxableSalary(formatAmount(salaryStructure.getTaxableSalary()));
        vo.setPersonalTax(formatAmount(salaryStructure.getPersonalTax()));
        vo.setNetSalary(formatAmount(salaryStructure.getNetSalary()));
        vo.setIsMasked(false); // 标记为未脱敏数据

        return vo;
    }

    /**
     * 将SalaryStructure转换为EmployeeSalaryVo（敏感信息模糊处理）
     *
     * @param salaryStructure 薪资结构实体
     * @return 员工薪资VO
     */
    private EmployeeSalaryVo convertToEmployeeSalaryVo(SalaryStructure salaryStructure) {
        EmployeeSalaryVo vo = new EmployeeSalaryVo();
        vo.setStructureId(salaryStructure.getStructureId());
        vo.setEmployeeNo(salaryStructure.getEmployeeNo());
        vo.setEmployeeName(salaryStructure.getEmployeeName());
        vo.setDepartment(salaryStructure.getDepartment());
        vo.setYearMonth(salaryStructure.getYearMonth());
        vo.setShouldAttendanceDays(salaryStructure.getShouldAttendanceDays());
        vo.setAbsenceDays(salaryStructure.getAbsenceDays());
        vo.setPaidAttendanceDays(salaryStructure.getPaidAttendanceDays());

        // 时间类型转换
        vo.setCreateTime(salaryStructure.getCreateTime());
        vo.setUpdateTime(salaryStructure.getUpdateTime());

        // 对薪资相关字段进行模糊处理
        vo.setJobLevelSalary(salaryStructure.getJobLevelSalary());
        vo.setBaseSalary(iSalaryStructureService.maskSalaryAmount(salaryStructure.getBaseSalary()));
        vo.setPositionSalary(iSalaryStructureService.maskSalaryAmount(salaryStructure.getPositionSalary()));
        vo.setPerformanceSalary(iSalaryStructureService.maskSalaryAmount(salaryStructure.getPerformanceSalary()));
        vo.setDutyAllowance(iSalaryStructureService.maskSalaryAmount(salaryStructure.getDutyAllowance()));
        vo.setAbsenceDeduction(iSalaryStructureService.maskSalaryAmount(salaryStructure.getAbsenceDeduction()));
        vo.setMealAllowance(iSalaryStructureService.maskSalaryAmount(salaryStructure.getMealAllowance()));
        vo.setOtherAdjustment(iSalaryStructureService.maskSalaryAmount(salaryStructure.getOtherAdjustment()));
        vo.setMealDeduction(iSalaryStructureService.maskSalaryAmount(salaryStructure.getMealDeduction()));
        vo.setGrossSalary(iSalaryStructureService.maskSalaryAmount(salaryStructure.getGrossSalary()));
        vo.setPensionDeduction(iSalaryStructureService.maskSalaryAmount(salaryStructure.getPensionDeduction()));
        vo.setUnemploymentDeduction(
                iSalaryStructureService.maskSalaryAmount(salaryStructure.getUnemploymentDeduction()));
        vo.setMedicalDeduction(iSalaryStructureService.maskSalaryAmount(salaryStructure.getMedicalDeduction()));
        vo.setMajorMedicalDeduction(
                iSalaryStructureService.maskSalaryAmount(salaryStructure.getMajorMedicalDeduction()));
        vo.setSocialInsurancePersonal(
                iSalaryStructureService.maskSalaryAmount(salaryStructure.getSocialInsurancePersonal()));
        vo.setHousingFundPersonal(iSalaryStructureService.maskSalaryAmount(salaryStructure.getHousingFundPersonal()));
        vo.setSocialHousingTotal(iSalaryStructureService.maskSalaryAmount(salaryStructure.getSocialHousingTotal()));
        vo.setTaxableSalary(iSalaryStructureService.maskSalaryAmount(salaryStructure.getTaxableSalary()));
        vo.setPersonalTax(iSalaryStructureService.maskSalaryAmount(salaryStructure.getPersonalTax()));
        vo.setNetSalary(iSalaryStructureService.maskSalaryAmount(salaryStructure.getNetSalary()));
        vo.setIsMasked(true); // 标记为已脱敏数据

        return vo;
    }

    /**
     * 格式化金额显示
     *
     * @param amount 金额
     * @return 格式化后的金额字符串
     */
    private String formatAmount(java.math.BigDecimal amount) {
        if (amount == null) {
            return "0.00";
        }

        // 移除低版本不兼容的setScientificNotation，仅保留核心格式化
        java.text.DecimalFormat df = new java.text.DecimalFormat("#,##0.00");
        return df.format(amount);
    }

    /**
     * Date转LocalDateTime
     *
     * @param date Date对象
     * @return LocalDateTime对象
     */
    private java.time.LocalDateTime dateToLocalDateTime(java.util.Date date) {
        if (date == null) {
            return null;
        }
        return date.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime();
    }
}
